package cn.lqz.bucttrain.service.impl;

import cn.lqz.bucttrain.contants.TrainConstants;
import cn.lqz.bucttrain.enums.*;
import cn.lqz.bucttrain.exceptions.BaseException;
import cn.lqz.bucttrain.mapper.TrainMapper;
import cn.lqz.bucttrain.pojo.dto.TrainCreateOrUpdateDTO;
import cn.lqz.bucttrain.pojo.dto.TrainPageQueryDTO;
import cn.lqz.bucttrain.pojo.entity.Train;
import cn.lqz.bucttrain.pojo.vo.PageResultVO;
import cn.lqz.bucttrain.service.TrainService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class TrainServiceImpl implements TrainService {
    @Resource
    private TrainMapper trainMapper;

    /**
     * 查询
     * @param trainPageQueryDTO
     * @return
     */
    @Override
    public PageResultVO loadTrainList(TrainPageQueryDTO trainPageQueryDTO) {
        log.info("加载或查询列车列表：{}",trainPageQueryDTO);
        PageHelper.startPage(trainPageQueryDTO.getPageNo(),trainPageQueryDTO.getPageSize());
        Page<Train> page = trainMapper.findBatch(trainPageQueryDTO);
        return new PageResultVO(trainPageQueryDTO.getPageNo(),trainPageQueryDTO.getPageSize(),page.getTotal(),page.getResult());
    }

    /**
     * 删除
     * @param trainId
     */
    @Override
    public void deleteTrain(Long trainId) {
        log.info("删除列车：trainId={}",trainId);
        Train train = trainMapper.findByTrainId(trainId);
        if (null==train){
            throw new BaseException(ResponseCodeEnum.CODE_600);
        }
        // 列车已发车并且停车时间晚于当前时间，其列车处于启用状态
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startTime = train.getStartTime();
        LocalDateTime stopTime = train.getStopTime();
        if (startTime!=null&&stopTime!=null&& startTime.isBefore(now) && stopTime.isAfter(now) && TrainStatusEnum.ENABLE.getStatus().equals(train.getStatus())){
            throw new BaseException(ResponseCodeEnum.CODE_400.getCode(),"列车运行中，无法删除");
        }
        trainMapper.deleteByTrainId(trainId);
    }

    /**
     * 添加或修改
     * @param trainCreateOrUpdateDTO
     */
    @Override
    public void addOrUpdateTrain(TrainCreateOrUpdateDTO trainCreateOrUpdateDTO) {
        log.info("添加或修改：{}",trainCreateOrUpdateDTO);
        Train train = new Train();
        BeanUtils.copyProperties(trainCreateOrUpdateDTO,train);
        Long trainId = trainCreateOrUpdateDTO.getTrainId();
        if (null==trainId){ // 添加
            // 插入
            trainMapper.insert(train);
        }else{ // 修改
            Train existTrain = trainMapper.findByTrainId(trainId);
            if (null==existTrain){
                throw new BaseException(ResponseCodeEnum.CODE_600);
            }
            // 如果要将列车设置为禁用或维修
            if (ArrayUtils.contains(new int[]{TrainStatusEnum.DISABLE.getStatus(),TrainStatusEnum.FIX.getStatus()},train.getStatus())){
                // 列车必须处于停车状态
                LocalDateTime now = LocalDateTime.now();
                LocalDateTime startTime = existTrain.getStartTime();
                LocalDateTime stopTime = existTrain.getStopTime();
                if (startTime!=null&&stopTime!=null&& startTime.isBefore(now) && stopTime.isAfter(now) && TrainStatusEnum.ENABLE.getStatus().equals(existTrain.getStatus())){
                    throw new BaseException(ResponseCodeEnum.CODE_400.getCode(),"列车运行中，无法修改状态");
                }
            }
            // 修改
            trainMapper.update(train);
        }
    }

    /**
     * 导出列车excel表
     * @param trainList
     * @param response
     */
    @Override
    public void exportOrderExcel(List<Train> trainList, HttpServletResponse response) {
        log.info("列车：导出excel表");
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/列车报表.xlsx");
        try{
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            for(int i=1;i<=trainList.size();i++){
                XSSFRow xssfRow = sheet.createRow(i);
                for(int j=0;j<8;j++){
                    xssfRow.createCell(j);
                }
            }
            for(int i=0;i<trainList.size();i++){
                Train train = trainList.get(i);
                XSSFRow row = sheet.getRow(i + 1);
                row.getCell(0).setCellValue(train.getTrainId());
                row.getCell(1).setCellValue(train.getTrainNumber());
                row.getCell(2).setCellValue(TrainTypeEnum.getByType(train.getType()).getDescription());
                LocalDateTime startTime = train.getStartTime();
                row.getCell(3).setCellValue(startTime==null?"":String.valueOf(startTime));
                LocalDateTime stopTime = train.getStopTime();
                row.getCell(4).setCellValue(stopTime==null?"":String.valueOf(stopTime));
                row.getCell(5).setCellValue(train.getBusinessRow()* TrainConstants.BUSINESS_ROW_SEAT);
                row.getCell(6).setCellValue(train.getCommonRow()*TrainConstants.COMMON_ROW_SEAT);
                row.getCell(7).setCellValue(TrainStatusEnum.getByStatus(train.getStatus()).getDescription());
            }
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);
            excel.close();
            inputStream.close();
        }catch (Exception e){
            log.error("订单导出excel表异常",e);
            throw new BaseException(ResponseCodeEnum.CODE_500);

        }
    }
}
